<template>
  <div class="container">
    <div class="user-header">
      <el-button
        type="primary"
        v-if="permission.includes('menu:add')"
        @click="handleAdd"
        >新增菜单</el-button
      >
    </div>
    <!-- table表单 -->
    <el-table
      :data="menusTableData"
      style="width: 100%; margin-bottom: 20px"
      row-key="id"
      border
      default-expand-all
    >
      <el-table-column label="菜单名称" prop="label" sortable />
      <el-table-column width="80" label="菜单图标" prop="icon">
        <template #default="scope">
          <div v-if="scope.row.icon">
            <el-icon class="el-input__icon">
              <component :is="scope.row.icon" />
            </el-icon>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="权限标识" prop="perms" sortable />
      <el-table-column label="菜单路由" prop="path" sortable />

      <!-- 菜单类型带颜色标签 -->
      <el-table-column label="菜单类型" prop="menu_type" sortable>
        <template #default="{ row }">
          <el-tag :type="getTagType(row.menu_type)" effect="dark">
            {{ getMenuTypeLabel(row.menu_type) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="菜单顺序" prop="sort" sortable />
      <el-table-column label="组件名称" prop="url" sortable />
      <el-table-column label="备注" prop="remark" sortable />

      <el-table-column label="操作" width="160">
        <template #="scope">
          <el-button
            type="primary"
            size="mini"
            v-if="permission.includes('menu:update')"
            @click="handleEdit(scope.row)"
            >编辑</el-button
          >
          <el-button
            type="danger"
            size="mini"
            v-if="permission.includes('menu:delete')"
            @click="handleDelete(scope.row)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <!-- 菜单弹窗 -->
    <el-dialog
      @close="dialogClose"
      style="width: 550px"
      v-model="editDialogVisibleAdd"
      :title="action == 'add' ? '新增菜单' : '编辑菜单'"
    >
      <el-form
        label-width="auto"
        ref="ruleFormRef"
        :model="queryModel"
        :rules="rules"
      >
        <el-form-item label="上级菜单">
          <el-tree-select
            v-model="queryModel.parent_id"
            :data="TreeData"
            :render-after-expand="false"
            :check-strictly="true"
            :props="treeSelectProps"
            @change="_change"
            style="width: 240px"
          />
        </el-form-item>
        <el-form-item label="菜单类型">
          <el-radio-group v-model="queryModel.menu_type" @change="menuChange">
            <el-radio :value="0">目录</el-radio>
            <el-radio :value="1">菜单</el-radio>
            <el-radio :value="2">按钮</el-radio>
          </el-radio-group>
        </el-form-item>
        <!-- :prefix-icon="Search" -->
        <el-form-item label="菜单图标选择">
          <el-select
            style="width: 240px"
            v-model="queryModel.icon"
            placeholder="请菜单选择图标"
          >
            <el-option
              v-for="(icon, name) in iconList"
              :key="name"
              :label="name"
              :value="name"
            >
              <el-icon style="vertical-align: middle">
                <component :is="icon" />
              </el-icon>
              <span style="margin-left: 8px">{{ name }}</span>
            </el-option>
          </el-select>
        </el-form-item>

        <el-form-item
          v-for="item in viewMap[queryModel.menu_type]"
          :key="item.key"
          :label="item.label"
          :prop="item.key"
          :required="['name', 'path', 'label'].includes(item.key)"
        >
          <el-input
            v-if="item.key === 'sort'"
            type="number"
            style="width: 350px"
            v-model="queryModel[item.key]"
          ></el-input>
          <el-input
            v-else-if="item.key === 'icon'"
            style="width: 350px"
            v-model="queryModel[item.key]"
          ></el-input>

          <el-input
            v-else-if="item.key === 'label'"
            style="width: 350px"
            v-model="queryModel[item.key]"
          ></el-input>
          <el-input
            v-else-if="item.key === 'name'"
            style="width: 350px"
            v-model="queryModel[item.key]"
          ></el-input>
          <el-input
            v-else-if="item.key === 'path'"
            style="width: 350px"
            v-model="queryModel[item.key]"
          ></el-input>
          <el-input
            v-else
            style="width: 350px"
            v-model="queryModel[item.key]"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <div style="margin-left: auto">
            <el-button @click="submit(ruleFormRef)" type="success"
              >确定</el-button
            >
            <el-button @click="cancel"> 取消</el-button>
          </div>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script setup>
import {
  ref,
  reactive,
  getCurrentInstance,
  onMounted,
  nextTick,
  watch,
} from "vue";
import { djSelect, deleteMenu, updateMenu, addMenu } from "@/api/index.js";
import { ElMessage, ElMessageBox } from "element-plus";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";
import { useAllDataStore } from "@/stores";
let allDataStore = useAllDataStore();
let permission = ref(allDataStore.state.permissionList);
// 可选图标列表（你也可以筛选你想用的）
const iconList = ElementPlusIconsVue;

let editDialogVisibleAdd = ref(false);
const menusTableData = ref([]);
let ruleFormRef = ref();
let queryModel = reactive({
  menu_type: 0,
  name: "",
  path: "",
  label: "",
});
const treeSelectProps = {
  value: "value",
  label: "label",
  children: "children",
};
let TreeData = ref([]);
let rules = ref({
  name: [
    {
      required: true,
      message: "路由名称不能为空",
      trigger: "blur",
    },
  ],
  path: [
    {
      required: true,
      message: "路由路径不能为空",
      trigger: "blur",
    },
  ],
  perms: [
    {
      required: true,
      message: "标识不能为空",
      trigger: "blur",
    },
  ],
  label: [
    {
      required: true,
      message: "菜单名称不能为空",
      trigger: "blur",
    },
  ],
});
let viewMap = ref([
  [
    // { value: 0, label: "菜单类型", key: "M", show: false },
    { value: 1, label: "显示排序", key: "sort" },
    { value: 2, label: "路由名称", key: "name" },
    { value: 3, label: "路由路径", key: "path" },
    { value: 4, label: "前段view页面", key: "url" },
    { value: 5, label: "菜单名称", key: "label" },
    { value: 6, label: "备注", key: "remark" },
  ],
  [
    // { value: 0, label: "菜单类型", key: "C" },
    { value: 1, label: "显示排序", key: "sort" },
    { value: 2, label: "路由名称", key: "name" },
    { value: 4, label: "路由路径", key: "path" },
    { value: 5, label: "前段view页面", key: "url" },
    { value: 6, label: "菜单名称", key: "label" },
    { value: 7, label: "备注", key: "remark" },
  ],
  [
    // { value: 0, label: "菜单类型", key: "F" },
    { value: 1, label: "显示排序", key: "sort" },
    { value: 2, label: "菜单标识", key: "perms" },
    { value: 3, label: "菜单名称", key: "label" },
    { value: 4, label: "备注", key: "remark" },
  ],
]);

// 编辑弹窗数据
const editDialogVisible = ref(false);
const editForm = reactive({
  id: null,
  label: "",
  sort: null,
  menu_type: "",
  path: "",
  url: "",
  name: "",
  label: "",
  remark: "",
  perms: "",
  icon: "",
  parent_id: "",
});
const resetQueryModel = () => {
  Object.keys(queryModel).forEach((key) => {
    if (key === "menu_type") {
      queryModel[key] = 0;
    } else if (key === "parent_id") {
      queryModel[key] = 0;
    } else {
      queryModel[key] = "";
    }
  });
};

let cancel = () => {
  ruleFormRef.value.resetFields();
  editDialogVisibleAdd.value = false;
};
let menuChange = (e) => {
  ruleFormRef.value.resetFields();
};
// let dialogClose = () => {
//   Object.keys(queryModel).forEach((key) => {
//     queryModel[key] = "";
//     if (key === "menu_type") {
//       queryModel[key] = 0;
//     }
//   });
//   ruleFormRef.value.resetFields();
// };
let dialogClose = () => {
  resetQueryModel();
  ruleFormRef.value.resetFields();
};
const action = ref("add");
// 添加弹窗
let handleAdd = async () => {
  action.value = "add";
  resetQueryModel();
  editDialogVisibleAdd.value = true;
};

// 打开编辑弹窗
const handleEdit = (val) => {
  action.value = "edit";
  editDialogVisibleAdd.value = true;
  Object.keys(val).forEach((key) => {
    if (["children", "is_delete", "create_time", "update_time"].includes(key)) {
      return;
    }
    queryModel[key] = val[key];
    if (key === "menu_type") {
      queryModel[key] = unFilterToString(val[key]);
    }
  });
};

const submit = async (formEl) => {
  if (!formEl) return;
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      let cp = JSON.parse(JSON.stringify(queryModel));
      cp.menu_type = filterToString(cp.menu_type);
      if (action.value === "add") {
        let res = await addMenu(cp);
        if (res.data.code === 200) {
          editDialogVisibleAdd.value = false;
          ElMessage({
            showClose: true,
            type: "success",
            message: "添加成功",
          });
          getMenusTableData();
        } else {
          ElMessage.error(res.data.msg || "添加失败");
        }
      } else if (action.value === "edit") {
        let res = await updateMenu(cp);
        if (res.data.code === 200) {
          editDialogVisibleAdd.value = false;
          ElMessage({
            showClose: true,
            type: "success",
            message: "修改成功",
          });
          getMenusTableData();
        } else {
          ElMessage.error(res.data.msg || "修改成功");
        }
      }
    } else {
      console.log("提交失败!", fields);
    }
  });
};

// 获取菜单类型标签文字
const getMenuTypeLabel = (type) => {
  switch (type) {
    case "M":
      return "目录";
    case "C":
      return "菜单";
    case "F":
      return "按钮";
    default:
      return type || "";
  }
};

// 获取菜单类型对应的标签颜色
const getTagType = (type) => {
  switch (type) {
    case "M":
      return "info";
    case "C":
      return "success";
    case "F":
      return "danger";
    default:
      return "";
  }
};

let unFilterToString = (data) => {
  switch (data) {
    case "M":
      return 0;
    case "C":
      return 1;
    case "F":
      return 2;
  }
};

// let filterToLabel = (data, res = []) => {
//   data.map((item) => {
//     if (item.children) {
//       res.push({
//         value: item.id,
//         label: item.label,
//         children: filterToLabel(item.children),
//       });
//       return;
//     }
//     res.push({
//       value: item.id,
//       label: item.label,
//     });
//   });
//   return res;
// };
let filterToLabel = (data) => {
  return data.map((item) => {
    const node = {
      value: item.id,
      label: item.label,
    };
    if (item.children && item.children.length > 0) {
      node.children = filterToLabel(item.children);
    }
    return node;
  });
};

let filterToString = (data) => {
  switch (data) {
    case 0:
      return "M";
    case 1:
      return "C";
    case 2:
      return "F";
  }
};
// 获取全部菜单数据
const getMenusTableData = async () => {
  const { data } = await djSelect();
  TreeData.value = filterToLabel(data.data.data);
  menusTableData.value = data.data.data || [];
};
//删除方法
const handleDelete = async (val) => {
  try {
    await ElMessageBox.confirm("确定删除该菜单吗？", "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    });

    // 传单个id，不是数组
    const response = await deleteMenu({ id: val.id });

    const data = response.data || response;

    if (data.code === 200) {
      ElMessage({
        showClose: true,
        type: "success",
        message: "删除成功",
      });
      getMenusTableData(); // 刷新数据
    } else {
      ElMessage.error(data.msg || "删除失败");
    }
  } catch (error) {
    if (error !== "cancel") {
      ElMessage.error("删除失败，请查看控制台");
      console.error("删除失败：", error);
    }
  }
};

// 页面加载时拉取数据
onMounted(() => {
  //获取全部菜单数据
  getMenusTableData();
});
</script>

<style scoped lang="less"></style>
